import { $, Slot, component$, useSignal, useStyles$, useVisibleTask$ } from "@builder.io/qwik";
import type { ModalProps } from "./types";
import closeSvg from '../svgs/close.svg?raw'
import styles from './index.css?inline'
import { sleep } from "../tools";

const Modal = component$<ModalProps>((props) => {
    useStyles$(styles)
    const isInit = useSignal<boolean>(false);
    const visibleDone = useSignal<boolean>(false);
    const modalShow = useSignal<boolean>(true);
    const timer = useSignal<any>();
    const loading = useSignal<boolean>(false);

    useVisibleTask$(async ({ track }) => {
        const visible = track(() => props.visible)
        if (visible) isInit.value = true;
        if (timer.value) clearTimeout(timer.value);
        if (visible) {
            modalShow.value = true;
            await sleep(100)
            visibleDone.value = true;
        } else if (isInit.value) {
            timer.value = setTimeout(async () => {
                visibleDone.value = false
                await sleep(100)
                modalShow.value = false;
            }, 300)
        }
    })

    const onCancel = $(() => {
        props.onCancel && props.onCancel();
    })

    const onOk = $(async () => {
        const { onOk } = props;
        if (onOk) {
            if (onOk instanceof Promise) {
                loading.value = true;
                await onOk();
                loading.value = false;
            } else onOk();
        }
    })

    const onMaskClick = $(() => {
        const { maskClosable = true } = props;
        if (maskClosable) onCancel();
    })

    const { title,
        footer = true,
        customFooter,
        mask = true,
        visible,
        width = 500,
        style = {},
        center = true,
    } = props;

    const animate = visibleDone.value && visible


    return (
        <div class={["qrui-modal-root fixed w-full h-full",
            {
                "qrui-modal-center": center
            }
        ]}
            style={{
                display: modalShow.value ? 'block' : 'none',
                width: visibleDone.value ? '100%' : 0,
                height: visibleDone.value ? '100%' : 0,
            }}
        >
            <div onClick$={onMaskClick} style={{ display: mask ? "block" : "none", opacity: animate ? 1 : 0 }} class="qrui-modal-mask"></div>
            {isInit.value && (
                <div class="qrui-modal-wrapper" style={{ width, ...style }}>
                    <div class="qrui-modal-content flex flex-col rounded-[8px]" style={{ opacity: animate ? 1 : 0, transform: animate ? "scale(1) translateY(0)" : 'scale(0.8) translateY(50px)' }}>
                        <header class="qrui-modal-header flex items-center shrink-0 px-[20px] py-[10px]">
                            <div class="qrui-modal-title flex-1">
                                {title ?
                                    <b>{title}</b> :
                                    <Slot name="title" />
                                }
                            </div>
                            <div onClick$={onCancel} class="qrui-modal-close shrink-0 cursor-pointer" dangerouslySetInnerHTML={closeSvg}>
                            </div>
                        </header>
                        <section class="qrui-modal-body flex-1  px-[20px] py-[10px]">
                            <Slot></Slot>
                        </section>
                        <footer class="qrui-modal-footer flex items-center justify-end shrink-0 px-[20px] py-[10px]">
                            {footer && <div><button disabled={loading.value} onClick$={onCancel} class="px-[15px] py-[4px]">取消</button><button disabled={loading.value} onClick$={onOk} class="px-[15px] py-[4px]">确定</button></div>}
                            {customFooter && <Slot name="footer" />}
                        </footer>
                    </div>
                </div>
            )}
        </div>
    )
})

export default Modal;